package com.platform.common.util.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ZipUtil {

    private static final Log log = LogFactory.getLog(ZipUtil.class);

    /**
     * 压缩文件列表到某ZIP文件
     * 
     * @param zipFilename
     *            要压缩到的ZIP文件
     * @param paths
     *            文件列表，多参数
     * @throws Exception
     */
    public static void zip(String zipFilename, String... paths) throws Exception {
        zip(new FileOutputStream(zipFilename), paths);
    }

    /**
     * 压缩文件列表到输出流
     * 
     * @param os
     *            要压缩到的流
     * @param paths
     *            文件列表，多参数
     * @throws Exception
     */
    public static void zip(OutputStream os, String... paths) throws Exception {
        ZipOutputStream zos = new ZipOutputStream(os);
        for (String path : paths) {
            if (path.equals("")) {
                continue;
            }
            File file = new File(path);
            if (file.exists() && !file.isHidden()) {
                if (file.isDirectory()) {
                    zipDirectory(zos, file.getPath(), file.getName() + File.separator);
                } else {
                    zipFile(zos, file.getPath(), "");
                }
            }
        }
        zos.finish();
        zos.close();
    }

    public static void zip(HttpServletResponse response, String fileName, String... paths) throws Exception {
        String zipFileName = new String(fileName.getBytes(), "ISO8859-1") + ".zip";
        response.setContentType("application/zip");
        response.setHeader("content-disposition", "attachment;filename=" + zipFileName);
        zip(response.getOutputStream(), paths);
    }

    private static void zipDirectory(ZipOutputStream zos, String dirName, String basePath) throws Exception {
        File dir = new File(dirName);
        if (dir.exists()) {
            File files[] = dir.listFiles();
            if (files.length > 0) {
                for (File file : files) {
                    if (!file.isHidden()) {
                        if (file.isDirectory()) {
                            zipDirectory(zos, file.getPath(),
                                    basePath + file.getName().substring(file.getName().lastIndexOf(File.separator) + 1)
                                            + File.separator);
                        } else {
                            zipFile(zos, file.getPath(), basePath);
                        }
                    }
                    zos.flush();
                }
            } else {
                ZipEntry ze = new ZipEntry(basePath);
                zos.putNextEntry(ze);
            }
        }
    }

    private static void zipFile(ZipOutputStream zos, String filename, String basePath) throws Exception {
        File file = new File(filename);
        if (file.exists()) {
            FileInputStream fis = new FileInputStream(filename);
            ZipEntry ze = new ZipEntry(basePath + file.getName());
            zos.putNextEntry(ze);
            byte[] buffer = new byte[8192];
            int count = 0;
            while ((count = fis.read(buffer)) > 0) {
                zos.write(buffer, 0, count);
            }
            fis.close();
        }
    }

    public static boolean isZipFile(String filePath) {
        boolean flag = false;
        if (filePath.substring(filePath.lastIndexOf(".")).equalsIgnoreCase(".zip")) {
            flag = true;
        }
        return flag;
    }

    public static boolean isNotZipFile(String filePath) {
        boolean flag = true;
        if (filePath.substring(filePath.lastIndexOf(".")).equalsIgnoreCase(".zip")) {
            flag = false;
        }
        return flag;
    }

    /**
     * 解压缩
     * 
     * @param sZipPathFile
     *            要解压的文件
     * @param sDestPath
     *            解压到某文件夹
     * @return
     */
    public static List<String> unZip(String sZipPathFile, String sDestPath) {
        if (isNotZipFile(sZipPathFile)) {
            return null;
        }
        List<String> allFileName = new ArrayList<String>();
        try {
            // 先指定压缩档的位置和档名，建立FileInputStream对象
            FileInputStream fins = new FileInputStream(sZipPathFile);
            // 将fins传入ZipInputStream中
            ZipInputStream zins = new ZipInputStream(fins, Charset.forName("gbk"));
            ZipEntry ze = null;
            byte[] ch = new byte[256];
            while ((ze = zins.getNextEntry()) != null) {
                String fileName = ze.getName();
                fileName = fileName.replace("\\", "/");
                int index = fileName.indexOf("/") + 1;
                fileName = fileName.substring(index);
                
                File zfile = new File(sDestPath + fileName);
                File fpath = new File(zfile.getParentFile().getPath());
                if (ze.isDirectory() || fileName.endsWith("/")) {
                    if (!zfile.exists()) {
                        zfile.mkdirs();
                    }
                    zins.closeEntry();
                } else {
                    if (!fpath.exists()) {
                        fpath.mkdirs();
                    }
                    //判断文件是否是目录
                    if (zfile.isDirectory()) {
                        if (!zfile.exists()) {
                            zfile.mkdirs();
                        }
                    } else {
                        
                        FileOutputStream fouts = new FileOutputStream(zfile);
                        int i;
                        allFileName.add(zfile.getAbsolutePath());
                        while ((i = zins.read(ch)) != -1) {
                            fouts.write(ch, 0, i);
                        }
                        zins.closeEntry();
                        fouts.close();
                    }
                }
            }
            fins.close();
            zins.close();
        } catch (Exception e) {
            log.error("unZip error 解压缩失败!!:", e);
        }
        return allFileName;
    }

    /**
     * 
     * @author cjy
     * @Description: 重命名文件
     * @param @param 旧的文件名称(地址+文件名)
     * @param @param 新的文件名(地址+文件名)
     * @param @return   
     * @return boolean  是否修改成功的标识
     * @date 2017-5-17
     */
    public static boolean renameFile(String oldFileName, String newFileName) {
        if (StringUtils.isEmpty(oldFileName)) {
            return false;
        }
        if (StringUtils.isEmpty(newFileName)) {
            return false;
        }
        File file = new File(oldFileName);
        File newFile = new File(newFileName);
        file.renameTo(newFile);
        return true;
    }

}